﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Effects.Effects.GuiParts
{

    /// <summary>
    ///  Simple 2 pole switch. Reacts on clicking it by raising an event.
    /// </summary>
    public partial class Footswitch : UserControl
    {

        #region turning_on_off

        /// <summary>
        ///  Indicates whether is Footswitch ON or OFF
        /// </summary>
        private bool on;

        /// <summary>
        ///  Gets or sets On/Off property of the footswtich.
        /// </summary>
        public bool On
        {
            get { return on; }
            set {  TurnOn(value);}
        }

        /// <summary>
        ///  Turns footswitch On.
        /// </summary>
        public void TurnOn()
        {
            TurnOn(true);
        }

        /// <summary>
        ///  Turns footswitch Off.
        /// </summary>
        public void TurnOff()
        {
            TurnOn(false);
        }

        /// <summary>
        ///  Turns footswtich on/off.
        /// </summary>
        /// <param name="on">True - turns on, false - turns off </param>
        public void TurnOn(bool on)
        {
            if (this.on != on)
            {
                this.on = on;
                RefreshMultiThread();
                if (this.Switched != null)
                {
                    FootswitchSwitchedEventArgs args = new FootswitchSwitchedEventArgs(on);
                    this.Switched(this, args);
                }

            }
        }

        /// <summary>
        ///  Turns switch on/off but doesn't raises the Switched event.
        /// </summary>
        /// <param name="on"> On/Off argument: true - on, false - off </param>
        public void SetValue(bool on)
        {
            this.on = on;
            RefreshMultiThread();
        }

        #endregion

        #region constructor
        // constructor

        /// <summary>
        ///  Creates new footswitch
        /// </summary>
        public Footswitch()
        {
            InitializeComponent();
            this.BackColor = System.Drawing.Color.Transparent;
            this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                          ControlStyles.UserPaint |
                          ControlStyles.DoubleBuffer, true);
            this.on = false;

            this.onImage  = Image.FromStream(new System.IO.MemoryStream(global::Effects.GuiParts.Resources.Footswitch.SwitchUp));
            this.offImage = Image.FromStream(new System.IO.MemoryStream(global::Effects.GuiParts.Resources.Footswitch.SwitchDown));
            this.Size = onImage.Size;

            refreshInvoker = new MethodInvoker(this.Refresh);
        }

        #endregion

        #region main_work
        // logic of the class

        /// <summary>
        ///  Occurs when Footswitch is switched either on or off.
        /// </summary>
        public event FootswitchSwitchedEventHandler Switched;

        /// <summary>
        ///  Image displayed when Footswitch is on.
        /// </summary>
        private Image onImage;

        /// <summary>
        ///  Image displayed when Footswitch is off.
        /// </summary>
        private Image offImage;

        /// <summary>
        ///  Paints the control to the screen.
        /// </summary>
        /// <param name="e"> Paint event arguments </param>
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (on)
                g.DrawImage(onImage,0,0);
            else
                g.DrawImage(offImage,0,0);
            
        }

        /// <summary>
        ///  Reacts on click on the Footswitch and turns it to the other state.
        /// </summary>
        /// <param name="e"> Event arguments </param>
        /// <remarks>
        ///  <para>
        ///   Everytime user clicks the footswitch it changes it state (turns on or off) and raised <see cref="Footswitch.Switched"/> event with the new state.
        ///  </para>
        /// </remarks>
        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            TurnOn(!on);
        }

        #endregion

        #region refresh_multi_thread
        // refreshing the control from all threads

        /// <summary>
        ///  Invoker for Refresh method.
        /// </summary>
        protected MethodInvoker refreshInvoker;

        /// <summary>
        ///  Refresh method accessible from all threads
        /// </summary>
        public void RefreshMultiThread()
        {
            if (InvokeRequired)
                BeginInvoke(refreshInvoker);
            else
                Refresh();
        }
        #endregion
    }
}
